
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkConcaveToTriangles.h"

#define SIZE    SkIntToScalar(150)

typedef void (*PathProc)(SkPath*);

static void make_path0(SkPath* path)
    {
    SkRect r;
    r.set(0, 0, SIZE, SIZE);
    path->addRect(r);
    }

static void make_path1(SkPath* path)
    {
    SkRect r;
    r.set(0, 0, SIZE, SIZE);
    path->addRoundRect(r, SIZE/4, SIZE/4);
    }

static void make_path2(SkPath* path)
    {
    SkRect r;
    r.set(0, 0, SIZE, SIZE);
    path->addOval(r);
    }

static const PathProc gProcs[] =
    {
    make_path0,
    make_path1,
    make_path2,
    };

#define COUNT_PROCS SK_ARRAY_COUNT(gProcs)

class TriangleView : public SkView
    {
    public:
        SkPath fPaths[COUNT_PROCS];

        TriangleView()
            {
            for (size_t i = 0; i < COUNT_PROCS; i++)
                {
                gProcs[i](&fPaths[i]);
                }
            }

    protected:
        // overrides from SkEventSink
        virtual bool onQuery(SkEvent* evt)
            {
            if (SampleCode::TitleQ(*evt))
                {
                SampleCode::TitleR(evt, "Triangles");
                return true;
                }
            return this->INHERITED::onQuery(evt);
            }

        void drawBG(SkCanvas* canvas)
            {
            canvas->drawColor(SK_ColorGRAY);
            }

        static void draw_path(SkCanvas* canvas, const SkPaint& pathPaint,
                              const SkPath& path, const SkPaint& triPaint)
            {
            canvas->drawPath(path, pathPaint);

            int n = path.getPoints(NULL, 0);
            SkPoint* pts = new SkPoint[n];
            path.getPoints(pts, n);

            SkTDArray<SkPoint> triangles;
            if (SkConcaveToTriangles(n, pts, &triangles))
                {
                canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
                                     triangles.count(), triangles.begin(), NULL,
                                     NULL, NULL, NULL, 0, triPaint);
                }

            SkPaint paint;
            paint.setColor(SK_ColorGREEN);
            paint.setStrokeWidth(SkIntToScalar(4));
            canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts, paint);
            delete[] pts;
            }

        virtual void onDraw(SkCanvas* canvas)
            {
            this->drawBG(canvas);

            canvas->translate(SIZE/2, SIZE/2);

            SkPaint pathPaint, triPaint;

            pathPaint.setColor(SK_ColorBLUE);
            pathPaint.setStrokeWidth(SIZE / 12);

            triPaint.setColor(SK_ColorRED);
            triPaint.setStyle(SkPaint::kStroke_Style);

            for (size_t i = 0; i < COUNT_PROCS; i++)
                {
                pathPaint.setStyle(SkPaint::kFill_Style);
                draw_path(canvas, pathPaint, fPaths[i], triPaint);

                canvas->save();
                canvas->translate(0, SIZE * 6 / 5);

                pathPaint.setStyle(SkPaint::kStroke_Style);
                draw_path(canvas, pathPaint, fPaths[i], triPaint);

                canvas->restore();
                canvas->translate(SIZE * 6 / 5, 0);
                }
            }

    private:
        typedef SkView INHERITED;
    };

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory()
    {
    return new TriangleView;
    }
static SkViewRegister reg(MyFactory);

